package com.ning.parking.service.impl;

import cn.hutool.core.bean.BeanUtil;
import cn.hutool.core.collection.CollectionUtil;
import cn.hutool.core.util.ObjectUtil;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.ning.parking.domain.ParkingLotBaseInfo;
import com.ning.parking.domain.ParkingLotBlacklist;
import com.ning.parking.domain.ParkingLotMonthlyApply;
import com.ning.parking.domain.ParkingLotWhitelist;
import com.ning.parking.domain.VO.Pagination;
import com.ning.parking.domain.dto.ParkingLotBlacklistPageDto;
import com.ning.parking.domain.dto.ParkingLotBlacklistSaveUpdateDTO;
import com.ning.parking.domain.dto.ParkingLotCarRelationGroupEntity;
import com.ning.parking.service.ParkingLotBaseInfoService;
import com.ning.parking.service.ParkingLotBlacklistService;
import com.ning.parking.mapper.ParkingLotBlacklistMapper;
import com.scsonic.common.enums.StatusEnum;
import com.scsonic.common.enums.caryardmanage.CarGroupManageDataTypeEnum;
import com.scsonic.common.enums.caryardmanage.CarWarningGroupTypeEnum;
import com.scsonic.common.enums.caryardmanage.PeriodValidityTypeEnum;
import com.scsonic.common.enums.monthly.MonthlyStatusEnum;
import com.scsonic.framework.exception.BizException;
import com.scsonic.framework.util.DateUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.time.LocalDate;
import java.util.*;
import java.util.function.Function;
import java.util.stream.Collectors;

/**
 *
 */
@Service
public class ParkingLotBlacklistServiceImpl extends ServiceImpl<ParkingLotBlacklistMapper, ParkingLotBlacklist>
    implements ParkingLotBlacklistService{

    @Autowired
    private ParkingLotBaseInfoService parkingLotBaseInfoService;

    @Autowired
    private ParkingLotCarRelationGroupService parkingLotCarRelationGroupService;

    @Autowired
    private ParkingLotCarWarningGroupService parkingLotCarWarningGroupService;

    @Override
    @Transactional(rollbackFor = Exception.class)
    public Long saveOrUpdateBlacklist(ParkingLotBlacklistSaveUpdateDTO dto) {
        ParkingLotBlacklist blacklist = BeanUtil.copyProperties(dto, ParkingLotBlacklist.class);
        checkByName(dto.getGroupName(), dto.getBlacklistId());
        //查询父停车场 id
        List<ParkingLotBaseInfo> baseInfos = parkingLotBaseInfoService.listByIds(dto.getParkingLotIds());
        Map<Long, ParkingLotBaseInfo> parentParkingLotMap = baseInfos.stream().collect(Collectors.toMap(ParkingLotBaseInfo::getParkingLotId, Function.identity()));
        //黑名单逻辑-------
        //黑名单车场关联
        if (Objects.nonNull(dto.getBlacklistId())) {
            parkingLotCarRelationGroupService.deleteByDataId(dto.getBlacklistId(), CarGroupManageDataTypeEnum.BLACKLIST);
        }
        if (PeriodValidityTypeEnum.IMMOBILIZATION.equals(dto.getPrescription()) && LocalDate.now().isAfter(DateUtils.toLocalDateTime(dto.getEndTime()).toLocalDate())) {
            blacklist.setStatus(StatusEnum.NO);
        }
        if (PeriodValidityTypeEnum.IMMOBILIZATION.equals(dto.getPrescription()) && !LocalDate.now().isAfter(DateUtils.toLocalDateTime(dto.getEndTime()).toLocalDate())) {
            blacklist.setStatus(StatusEnum.YES);
        }
        //黑名单新增或者修改
        saveOrUpdate(blacklist);
        List<ParkingLotCarRelationGroupEntity> relationGroups = new ArrayList<>();
        dto.getParkingLotIds().forEach(item -> {
            ParkingLotCarRelationGroupEntity relation = new ParkingLotCarRelationGroupEntity();
            relation.setParkingLotId(item);
            relation.setDataId(blacklist.getBlacklistId());
            relation.setDataType(CarGroupManageDataTypeEnum.BLACKLIST);
            relation.setParkingLotId(Objects.isNull(parentParkingLotMap.get(item).getParentId()) ? item : parentParkingLotMap.get(item).getParentId());
            relationGroups.add(relation);
        });
        parkingLotCarRelationGroupService.saveBatch(relationGroups);
        parkingLotCarRelationGroupService.deleteBySourceId(blacklist.getBlacklistId(),CarWarningGroupTypeEnum.BLACKLIST);
        //黑名单对应的预警记录
        //设置不通知，那么删除之前存在的(如果之前有记录)
        if (StatusEnum.NO.equals(dto.getNotice())) {
            return blacklist.getBlacklistId();
        }
        // 新增一个黑名单分组，就新增一个预警分组
        dto.setBlacklistId(blacklist.getBlacklistId());
        Long groupId = parkingLotCarWarningGroupService.saveOrUpdate(buildParkingLotCarWarningGroupSaveUpdateDTO(dto));
        //新增不同步
        if (Objects.isNull(dto.getBlacklistId())) {
            return blacklist.getBlacklistId();
        }
        //修改进行同步数据
        //List<ParkingLotCarGroupManageEntity> manageEntities = parkingLotCarGroupManageService.selectByDataId(dto.getBlacklistId(),CarGroupManageDataTypeEnum.BLACKLIST);
//        if (!CollectionUtil.isEmpty(manageEntities)) {
//            manageEntities.forEach(item -> {
//                item.setDataId(groupId);
//                item.setDataType(CarGroupManageDataTypeEnum.CAR_WARNING);
//                item.setSourceId(item.getId());
//                item.setId(null);
//                item.setRemark("黑名单同步");
//            });
//            parkingLotCarGroupManageService.saveBatch(manageEntities);
//        }
        return blacklist.getBlacklistId();
    }

    private Object buildParkingLotCarWarningGroupSaveUpdateDTO(ParkingLotBlacklistSaveUpdateDTO dto) {
       return this.lambdaQuery().eq(ParkingLotBlacklist::getBlacklistName,dto.getGroupName()).list();
    }

    private void checkByName(String groupName, Long blacklistId) {
        List<ParkingLotBlacklist> list = lambdaQuery().eq(ParkingLotBlacklist::getBlacklistName, groupName).list();
        if (ObjectUtil.isNotEmpty(list) && list.size() > 0) {
            throw new BizException(groupName+"名称重复");
        }
    }

    @Override
    public Pagination<ParkingLotBlacklist> selectPage(ParkingLotBlacklistPageDto pageBase) {
        //小于 大于
        Page<ParkingLotBlacklist> page = lambdaQuery()
                .like(ObjectUtil.isNotEmpty(pageBase.getCarLicense()), ParkingLotBlacklist::getCarLicense, pageBase.getCarLicense())
                .lt(ObjectUtil.isNotEmpty(pageBase.getStartTime()), ParkingLotBlacklist::getStartTime, pageBase.getStartTime())
                .gt(ObjectUtil.isNotEmpty(pageBase.getEndTime()), ParkingLotBlacklist::getEndTime, pageBase.getEndTime())
                .orderByDesc(ParkingLotBlacklist::getBlacklistId).page(pageBase.toPage());
        return Pagination.of(page);
    }

    @Override
    public ParkingLotBlacklist selectBlacklist(String carLicense, Date captureTime) {

        List<ParkingLotBlacklist> list = lambdaQuery()
                .eq(ParkingLotBlacklist::getCarLicense, carLicense)
                .orderByDesc(ParkingLotBlacklist::getStartTime)
                .last("limit 1")
                .list();

        if (list.size() == 0) {
            return null;
        }

        for (ParkingLotBlacklist one : list) {
            if(one==null){
                return one;
            }

            if (one.getPrescription() != null &&  one.getPrescription() == PeriodValidityTypeEnum.FOREVER) {
                return one;
            }

            Date startTime = one.getStartTime();
            Date endTime = new Date(one.getEndTime().getTime()+(1000*60*60*24));

            if (startTime==null||endTime==null){
                return null;
            }

            if (startTime.getTime() <= captureTime.getTime() && endTime.getTime() >= captureTime.getTime()) {
                return one;
            }
        }
        return null;
    }
}




